package module.StoreService.Impl;

import common.model.Entity.StoreEntity.Category;
import common.model.Entity.StoreEntity.Product;
import dao.StoreDao.CategoryDao;
import dao.StoreDao.ProductDao;
import dao.impl.StoreDaoImpl.CategoryDaoImpl;
import dao.impl.StoreDaoImpl.ProductDaoImpl;
import module.StoreService.ProductService;
import network.protocol.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Optional;

/**
 * {@code ProductServiceImpl} 是 {@link ProductService} 的实现类，
 * 提供商品（Product）的增删改查、库存管理、状态管理等功能。
 * <p>
 * 主要功能：
 * <ul>
 *     <li>根据 ID、名称、分类获取商品</li>
 *     <li>获取所有商品或统计商品总数</li>
 *     <li>创建、更新、删除商品</li>
 *     <li>检查商品是否存在、商品名称是否存在</li>
 *     <li>更新库存和上架/下架状态</li>
 * </ul>
 * <p>
 * 实现逻辑通过 {@link ProductDao} 与数据库交互，
 * 并使用 {@link Response} 封装统一的返回结果。
 * <p>
 * 类采用单例模式，请通过 {@link #getInstance()} 获取实例。
 */
public class ProductServiceImpl implements ProductService {
    private static final Logger logger = LoggerFactory.getLogger(ProductServiceImpl.class);
    private final ProductDao productDao = new ProductDaoImpl();
    private static final ProductServiceImpl INSTANCE = new ProductServiceImpl();

    /**
     * 私有构造函数，防止外部直接实例化。
     */
    private ProductServiceImpl() {}

    /**
     * 获取 {@code ProductServiceImpl} 的单例对象。
     *
     * @return 单例实例
     */
    public static ProductServiceImpl getInstance() {
        return INSTANCE;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<Optional<Product>> getProductById(long id) {
        try {
            Optional<Product> product = productDao.findById(id);
            return Response.success(product);
        } catch (Exception e) {
            logger.error("获取商品失败: id={}", id, e);
            return Response.error("获取商品失败: " + e.getMessage());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<Optional<Product>> getProductByName(String name) {
        try {
            Optional<Product> product = productDao.findByProductName(name);
            return Response.success(product);
        } catch (Exception e) {
            logger.error("获取商品失败: name={}", name, e);
            return Response.error("获取商品失败: " + e.getMessage());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<List<Product>> getAllProducts() {
        try {
            List<Product> products = productDao.findAll();
            return Response.success(products);
        } catch (Exception e) {
            logger.error("获取所有商品失败", e);
            return Response.error("获取所有商品失败: " + e.getMessage());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<List<Product>> getProductsByCategoryId(long categoryId) {
        try {
            List<Product> products = productDao.findByCategoryId(categoryId);
            return Response.success(products);
        } catch (Exception e) {
            logger.error("根据分类ID获取商品失败: categoryId={}", categoryId, e);
            return Response.error("根据分类ID获取商品失败: " + e.getMessage());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<List<Product>> getProductsByCategoryName(String categoryName) {
        try {
            List<Product> products = productDao.findByCategoryName(categoryName);
            return Response.success(products);
        } catch (Exception e) {
            logger.error("根据分类名称获取商品失败: categoryName={}", categoryName, e);
            return Response.error("根据分类名称获取商品失败: " + e.getMessage());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<Boolean> createProduct(Product product) {
        /* 1. 商品名校验 */
        Optional<Product> existing = productDao.findByProductName(product.getProductName());
        if (existing.isPresent()) {
            logger.warn("创建商品失败: 商品名称 '{}' 已存在", product.getProductName());
            return Response.error("商品名称已存在");
        }

        /* 2. 仅根据 categoryName 拿到 categoryId（不存在则自动创建） */
        String categoryName = product.getCategoryName();
        CategoryDao categoryDao = new CategoryDaoImpl();

        Optional<Category> opt = categoryDao.findByName(categoryName);
        long categoryId;
        if (opt.isPresent()) {
            categoryId = opt.get().getId();
        } else {
            Category newCat = new Category();
            newCat.setName(categoryName);
            categoryId = categoryDao.insertAndReturnId(newCat);
            logger.info("分类 '{}' 不存在，已自动创建，id={}", categoryName, categoryId);
        }

        /* 3. 把 categoryId 写回 Product */
        product.setCategoryId(categoryId);

        /* 4. 落库 */
        boolean result = productDao.save(product);
        return result ? Response.success(true) : Response.error("创建商品失败");
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<Boolean> updateProduct(Product product) {
        try {
            if (productDao.findById(product.getId()).isEmpty()) {
                logger.warn("更新商品失败: 未找到ID为 {} 的商品", product.getId());
                return Response.error("未找到指定商品");
            }

            boolean result = productDao.update(product);
            return result ? Response.success(true) : Response.error("更新商品失败");
        } catch (Exception e) {
            logger.error("更新商品失败: id={}", product.getId(), e);
            return Response.error("更新商品失败: " + e.getMessage());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<Boolean> deleteProduct(long id) {
        try {
            if (productDao.findById(id).isEmpty()) {
                logger.warn("删除商品失败: 未找到ID为 {} 的商品", id);
                return Response.error("未找到指定商品");
            }

            boolean result = productDao.deleteById(id);
            return result ? Response.success(true) : Response.error("删除商品失败");
        } catch (Exception e) {
            logger.error("删除商品失败: id={}", id, e);
            return Response.error("删除商品失败: " + e.getMessage());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<Long> getProductCount() {
        try {
            long count = productDao.count();
            return Response.success(count);
        } catch (Exception e) {
            logger.error("获取商品总数失败", e);
            return Response.error("获取商品总数失败: " + e.getMessage());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<Boolean> productExists(long id) {
        try {
            boolean exists = productDao.findById(id).isPresent();
            return Response.success(exists);
        } catch (Exception e) {
            logger.error("检查商品是否存在失败: id={}", id, e);
            return Response.error("检查商品是否存在失败: " + e.getMessage());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<Boolean> productNameExists(String name) {
        try {
            boolean exists = productDao.findByProductName(name).isPresent();
            return Response.success(exists);
        } catch (Exception e) {
            logger.error("检查商品名称是否存在失败: name={}", name, e);
            return Response.error("检查商品名称是否存在失败: " + e.getMessage());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<Boolean> updateProductStock(long id, int newStock) {
        try {
            Optional<Product> productOpt = productDao.findById(id);
            if (productOpt.isEmpty()) {
                logger.warn("更新商品库存失败: 未找到ID为 {} 的商品", id);
                return Response.error("未找到指定商品");
            }

            Product product = productOpt.get();
            product.setStock(newStock);
            boolean result = productDao.update(product);
            return result ? Response.success(true) : Response.error("更新商品库存失败");
        } catch (Exception e) {
            logger.error("更新商品库存失败: id={}", id, e);
            return Response.error("更新商品库存失败: " + e.getMessage());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<Boolean> updateProductStatus(long id, int status) {
        try {
            if (status != 0 && status != 1) {
                logger.warn("更新商品状态失败: 状态值 {} 无效，只能是0(下架)或1(上架)", status);
                return Response.error("状态值无效，只能是0(下架)或1(上架)");
            }

            Optional<Product> productOpt = productDao.findById(id);
            if (productOpt.isEmpty()) {
                logger.warn("更新商品状态失败: 未找到ID为 {} 的商品", id);
                return Response.error("未找到指定商品");
            }

            Product product = productOpt.get();
            product.setStatus(status);
            boolean result = productDao.update(product);
            return result ? Response.success(true) : Response.error("更新商品状态失败");
        } catch (Exception e) {
            logger.error("更新商品状态失败: id={}", id, e);
            return Response.error("更新商品状态失败: " + e.getMessage());
        }
    }
}
